The Var History

The Var keyword


Var and let might do almost the same job but under the hood var is a different breed

variables declared with var, are either function-scoped or global-scoped. They are visible through blocks => no block scope. and they are always hoisted and tolerate redeclaration ’ That’s the difference in a nutshell ’




		if (true) {
			var test = true; // if statement is a block and it should have a lexical environment 'modern JS feature'
			//But the var break this rule
		}
		console.log(test); // true, the variable lives after if. it should be undefined


note: If a code block is inside a function, then var becomes a function-level variable:


hoisted => raised so for example if we will assign a value to a variable that we declared with var at the first line of our code but the declaration is far down this normally should cause an error but it won’t So this code:



		function anything() {
			variable = "Hello"; // this should give an error => refrence error cant access before init but it works

			console.log(variable);

			var variable;
		}

		anything();


…Is technically the same as this (moved var phrase above):



		function anything() {
			var phrase;

			phrase = "Hello";

			console.log(phrase);
		}
		anything();


note: declaration is hoisted but the assignment is not so if we declare a variable and assigned it below but referenced it above it will run because the declaration is raised but it won’t be assigned any value so it will run but the variable will equal null




		var user = "Pete";

		var user = "John"; // this "var" does nothing (already declared) // ...it doesn't trigger an error

		console.log(user); // John


So how did they manage to work around this in the old days ’ IIFE ’


first before even saying how they managed to avoid the var why did they really want to avoid it? what did it cause

Global namespace pollution



reachability In a nutshell it means that all the variables we can currently reach and use will be put in the memory the others are discarded


values:



-unreachable: removed from memory by the garbage collector


Example


		let object = {
			value: "hi", //now the object is in the stack and it references the value stored in the heap
		};
		//this now is a reachable value (some address in the stack that references the value in the heap )


but if we do this in the same code



		object = null;
		//the address in the stack is now deleted and the value in the heap has nothing that points to it => unreachable
		//and here is where our friend Garbage Collector works and junks it to free the memory


if the references are interlinked more details here: https://javascript.info/garbage-collection#interlinked-objects

and you remove the root object that points to all the values the removed values are called Unreachable island


digging deeper into the GC the internal algorithm: it’s called ‘mark-and-sweep’ at it works as follows:






the JS engine applies some optimizations to this algorithm:





Back to global namespace pollution


As variables lose scope, they will be eligible for garbage collection. If they are scoped globally, then they will not be eligible for collection until the global namespace loses scope, and trust me you don’t want to have a lot of global scope variables.


a code like this one



		for (var i = 0; i < 2003000; i++) {
			var arra = [];
			arr.push(i * i + i);
		}


will add about 10,000 kb of memory usage that will not be collected and yes we used a var here so why is the var wrong? you might encounter some cases when you define variables in a block scope ‘if statement or a loop’ but in the old days it will be scoped in the global namespace


but if it was like this



		for (let i = 0; i < 2003000; i++) {
			let arra = [];
			arr.push(i * i + i);
		}


it would’ve been collected as soon as it exited the for-loop scope


Always remember keeping the values in a closure will ensure they are collected don’t know what closure is don’t worry we will talk about it another time


So how did they manage to avoid this ’ IIFE ’


IIFE => immediately-invoked function expressions it’s not something you should use but you have to know that you can do this an IIFE is



		(function () {
			var something = "idk";
			console.log(something);
		})(); //here it invoked as soon as it was created and we use it in this function context to do all what we need and then
		//it's removed from the memory by the GC


Question 1: why is it wrapped in parenthesis?



Question 2: why don’t we add a name?


there are other ways to do this in JS it doesn’t have to be a parenthesis


our history lesson now is done :)